package c3

import "fmt"

type Dog struct {
	Name   Name
	Breed  Breed
	Gender Gender
}

type (
	Name          string
	Breed         int
	Gender        int
	NameToDogFunc func(name Name) Dog
)

const (
	Bulldog Breed = iota
	Havanese
	Cavalier
	Poodle
)

const (
	Male Gender = iota
	Female
)

func DogSpawner(breed Breed, gender Gender) NameToDogFunc {
	return func(n Name) Dog {
		return Dog{
			Breed:  breed,
			Gender: gender,
			Name:   n,
		}
	}
}

func DogSpawnerCurry(breed Breed) func(gender Gender) NameToDogFunc {
	return func(gender Gender) NameToDogFunc {
		return func(name Name) Dog {
			return Dog{
				Breed:  breed,
				Gender: gender,
				Name:   name,
			}
		}
	}
}

var (
	maleHavaneseSpawner = DogSpawner(Havanese, Male)
	femalePoodleSpawner = DogSpawner(Poodle, Female)
)

func Currying() {
	bucky := DogSpawnerCurry(Havanese)(Male)("Bucky")
	fmt.Print(bucky.Name)

	havaneseSpawner := DogSpawnerCurry(Havanese)
	rocky := havaneseSpawner(Male)("Rocky")
	fmt.Print(rocky.Name)

	femaleHavanese := havaneseSpawner(Female)
	lola := femaleHavanese("Lola")
	dotty := femaleHavanese("Dotty")
	fmt.Print(lola.Name)
	fmt.Print(dotty.Name)

	tipsy := femalePoodleSpawner("tipsy")
	fmt.Print(tipsy.Name)
}
